#include "threadPool.h"

//初始化
void threadPoolInit(threadPool_t* pThreadPool,int workerNum){
    tidArrInit(&pThreadPool->pTidArr,workerNum);
    taskQueueInit(&pThreadPool->pTaskQueue);
    //别忘记初始化锁和条件变量
    pthread_mutex_init(&pThreadPool->mutex,NULL);
    pthread_cond_init(&pThreadPool->cond,NULL);
    //初始化退出标志位，初始都是0
    pThreadPool->exit_flag = 0;
}

//创建子线程worker
void makeWorker(threadPool_t* pThreadPool,int workerNum){
    for(int i=0;i<workerNum;i++){
        pthread_create(&pThreadPool->pTidArr.pArr[i],NULL,threadFunc,pThreadPool);
    }
}

//3.0服务端处理客户端发送的命令 线程入口函数
void* threadFunc(void* arg){
    threadPool_t* pThreadPool = (threadPool_t*)arg;
    printf("i am child tid : %lu\n",pthread_self());
    while(1){
        pthread_mutex_lock(&pThreadPool->mutex);
        while(pThreadPool->exit_flag == 0 && pThreadPool->pTaskQueue.size == 0){
            //在没有退出标志位为0（父进程没有让他退出）和任务队列为空时等待
            pthread_cond_wait(&pThreadPool->cond,&pThreadPool->mutex);
        }
        if(pThreadPool->exit_flag == 1){
            //释放锁
            pthread_mutex_unlock(&pThreadPool->mutex);
            //退出
            pthread_exit(NULL);
        }
        /* printf("before tid:%lu\n",pthread_self()); */
        int fd = deQueue(&pThreadPool->pTaskQueue);
        /* printf("after fd = %d connected! tid:%lu\n",fd,pthread_self()); */
        pthread_mutex_unlock(&pThreadPool->mutex);
        printf("===worker working with fd = %d...===\n",fd);

        int epfd = epoll_create(1);
        struct epoll_event event;
        event.events = EPOLLIN;
        event.data.fd = fd;
        //客户端fd加入监听
        epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&event);

        struct epoll_event readySet[10];
        char username[1024] = {0};

        recv_username(fd,username);

        printf("user name:%s\n",username);
        char server_path[2048];
        sprintf(server_path,"%s%s",PATH_PREFIX,username);
        /* printf("server path:%s\n",username); */

        path_stack_t path_stack;
        path_stack_init(&path_stack);

        while(1){
            int readyNum = epoll_wait(epfd,readySet,10,-1);
            for(int i=0;i<readyNum;i++){
                if(readySet[i].data.fd == fd){
                    char *parts[MAX_PARTS] = {NULL};
                    int count = recv_command(fd,parts);
                    /* printf("==count = %d\n",count); */
                    if(count == 0){
                        printf("客户端%s断开连接\n",username);
                        goto end;
                    }
                    for(int i=0;i<count;i++){
                        /* printf("i=%d\t%s\n",i,parts[i]); */
                    }
                    char result[1024] = {0};
                    //处理命令
                    deal_cmd(&path_stack, parts,count,server_path,result,fd);
                    //返回结果
                    send_result(fd,result);
                }
            }
        }
end:
        path_stack_destroy(&path_stack);
        close(fd);
    }
    pthread_exit(NULL);
}
//处理命令
int deal_cmd(path_stack_t* path_stack, char *parts[], int count, char* server_path, char* result, int netfd){
    char* command = parts[0];
    /* printf("in deal_cmd:server_path = %s\n",server_path); */
    /* printf("in deal_cmd:command = %s\n",parts[0]); */
    /* printf("in deal_cmd:command = %s\n",parts[1]); */
    if (strcmp(command, "cd") == 0) {
        /* printf("cd\n"); */
        cd_func(path_stack,server_path,parts[1],result);
    } else if (strcmp(command, "pwd") == 0) {
        /* printf("pwd\n"); */
        pwd_func(path_stack,result);
    } else if (strcmp(command, "ll") == 0) {
        /* printf("ll\n"); */
        if(count == 1){
            /* printf("ll,count = 1\n"); */
            ll_func(path_stack,server_path,".",result);
        }else if(count == 2){
            /* printf("ll,count = 2\n"); */
            ll_func(path_stack,server_path,parts[1],result);
        }
    } else if (strcmp(command, "ls") == 0){
        if(count == 1){
            /* printf("ls,count = 1\n"); */
            ls_func(path_stack,server_path,".",result);
        }else if(count == 2){
            /* printf("ls,count = 2\n"); */
            ls_func(path_stack,server_path,parts[1],result);
        }
    } else if (strcmp(command, "mkdir") == 0){
        /* printf("mkdir\n"); */
        mkdir_func(path_stack,server_path,parts[1],result);
    } else if (strcmp(command, "rmdir") == 0){
        /* printf("rmdir\n"); */
        rmdir_func(path_stack,server_path,parts[1],result);
    } else if (strcmp(command, "remove") == 0){
        /* printf("remove\n"); */
        remove_func(path_stack,server_path,parts[1],result);
    } else if (strcmp(command, "puts") == 0){
        /* printf("puts\n"); */
        //客户端上传文件
        char current_real_path[1024] = {0};                                                                              
        strcat(current_real_path,server_path);
        get_current_path_on_server(path_stack,current_real_path);
        strcat(current_real_path,parts[1]);
        printf("真实路径:%s\n",current_real_path);
        //服务端接收文件
        recv_file_from_client(netfd,current_real_path);
        /* int retv = recv_file_from_client(netfd,current_real_path); */
        /* if(retv == -1){ */
        /*     sprintf(result,"%s\n",strerror(errno)); */
        /* } */
    } else if (strcmp(command, "gets") == 0){
        /* printf("gets\n"); */
        //客户端下载文件
        char current_real_path[1024] = {0};
        strcat(current_real_path,server_path);
        get_current_path_on_server(path_stack,current_real_path);
        strcat(current_real_path,parts[1]);
        printf("真实路径:%s\n",current_real_path);
        //服务端发送文件
        /* if(access(current_real_path,F_OK) != 0){//目录不存在 */
        /*     printf("*****\n"); */
        /*     sprintf(result,"%s\n",strerror(errno)); */
        /*     return 0; */                                                                                             
        /* } */ 
        trans_file_to_client(netfd,current_real_path);
        /* if(retv == -1){ */
        /*     sprintf(result,"%s\n",strerror(errno)); */
        /* } */
    } else {
        //未知命令，不处理
        return 0;
    }
    return 0;
}
